//################################################################################
// MIT License
// Copyright (c) 2024 ZhangYihua
//
// Change Logs:
// Date           Author       Notes
// 2020-04-19     ZhangYihua   first version
//
// Description  : arbiter with strict priority
//################################################################################

module arb_sp #(
parameter           PORT_NUM                = 8
) ( 
input               [PORT_NUM-1:0]          req,        // raw request vector
output                                      req_exist,  // logic OR of all reqs
output              [PORT_NUM-2:0]          gnt_pos,    // position of current grant
output              [PORT_NUM-1:0]          gnt         // immediate grants according to req
);

//################################################################################
// define local varialbe and localparam
//################################################################################
reg                 [PORT_NUM-1:0]          req_or;

//################################################################################
// main
//################################################################################

// accumulate higher priority req
always@(*) begin:GEN_REQ_OR
    integer         i;

    req_or[0] = 1'b0;
    for (i=1; i<PORT_NUM; i=i+1) begin
         req_or[i] = req_or[i-1] | req[i-1];
    end
end

assign req_exist = |req;    // use additional resource for better timing
assign gnt_pos = req_or[PORT_NUM-1:1];

// mask lower priority req, and keep the highest priority req
assign gnt = req & (~req_or[0+:PORT_NUM]);

endmodule
